package com.primb.bench.common.module.http.service;

import com.cm.retrofit2.converter.file.FileConverterFactory;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.primb.bench.BuildConfig;
import com.primb.bench.R;
import com.primb.bench.base.IApplication;
import com.primb.netlibs.config.ApiConstants;
import com.primb.netlibs.converter.FastJsonConverterFactory;
import com.primb.netlibs.cookie.CookieManger;


import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;

/**
 * Created by Chen on 2017/4/13.
 * 功能描述：配置retrofit
 */

public class ApiClient {

    public static Retrofit retrofit;

    public static <T> T initService(Class<T> clazz) {
        if (retrofit == null) {
            OkHttpClient client = configHttpClient();
            retrofit = new Retrofit.Builder()
                    .baseUrl(ApiConstants.BASE_URL)
                    .addConverterFactory(FastJsonConverterFactory.create())
                    .addConverterFactory(FileConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(client)
                    .build();
        }
        return retrofit.create(clazz);
    }

    private static OkHttpClient configHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(httpLoggingInterceptor).addNetworkInterceptor(new StethoInterceptor());
        }
        builder.addInterceptor(chain -> {
            Request original = chain.request();
            HttpUrl url = original.url().newBuilder().build();
            Request request = original.newBuilder()
                    .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
                    .addHeader("Connection", "keep-alive")
                    .method(original.method(), original.body())
                    .url(url)
                    .build();
            return chain.proceed(request);
        });
        OkHttpClient client = builder
                .cookieJar(new CookieManger(IApplication.getInstance()))
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
//                .sslSocketFactory(getSSLSocketFactory(IApplication.getInstance().getResources().openRawResource(R.raw.zs)))
                .build();
        return client;
    }

    public static SSLSocketFactory getSSLSocketFactory(InputStream... certificates) {
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }

            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            return sslSocketFactory;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
